package com.zjhd.sealcutting.service.impl;

import com.zjhd.sealcutting.dao.FileUploadMapper;
import com.zjhd.sealcutting.domain.FileUpload;
import com.zjhd.sealcutting.service.FileUploadService;
import com.zjhd.sealcutting.utils.CompressUtil;
import com.zjhd.sealcutting.utils.DateUtil;
import com.zjhd.sealcutting.utils.ZipUtils;
import com.zjhd.sealcutting.utils.idgenerator.Sequence;
import com.zjhd.sealcutting.utils.response.ResponseResult;
import com.zjhd.sealcutting.utils.response.ResultGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * TODO  文件上传
 *
 * @author wangchao
 * @version 1.0
 * @date 2020/11/24 17:45
 */
@Service
public class FileUploadServiceImpl implements FileUploadService {

    //上传文件根目录
    private static final String UPLOAD_PATH = "upload";

    private String fileRootPath="/app/upload"; // 上传文件的根路径

    @Autowired
    private FileUploadMapper fileUploadMapper;

    /**
     * TODO  上传文件
     * @author wangchao
     * @date 2020/11/24 18:03
     * @param
     * @return
     */
    @Override
    public ResponseResult uploadFile(HttpServletRequest request) {
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        Sequence sequence = new Sequence();
        List<FileUpload> list = new ArrayList<>();
        MultipartFile file = null;
        OutputStream stream = null;
        InputStream in = null;
        File filePath = null;
        for (int i = 0; i < files.size(); ++i) {
            try {
                file = files.get(i);
                if (!file.isEmpty()) {
                    String fileName = file.getOriginalFilename();
                    String suffixName = fileName.substring(fileName.lastIndexOf("."));
                    long id = sequence.nextId();
                    String path = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date()) + id + suffixName;
                    filePath = new File(fileRootPath + path);
                    if (!filePath.getParentFile().exists()) {
                        filePath.getParentFile().mkdirs();
                    }

                    in = file.getInputStream();
                    stream = new FileOutputStream(filePath);
                    byte[] bytes = new byte[51200];
                    int len = 0;
                    while ((len = in.read(bytes)) != -1) {
                        stream.write(bytes, 0, len);
                    }
                    in.close();
                    stream.close();

                    String url = null;
                    if (System.getProperty("os.name").contains("Windows")) {
                        url = filePath.getPath().split("\\\\" + UPLOAD_PATH + "\\\\")[1];
                    } else {
                        url = filePath.getPath().split("/" + UPLOAD_PATH + "/")[1];
                    }

                    //组建表数据并存储
                    FileUpload upload = new FileUpload();
                    upload.setId(id + "");
                    upload.setUrl(url);
                    upload.setName(fileName);
                    upload.setType(suffixName.substring(1));
                    upload.setCreateTime(DateUtil.getCurrentTime());
                    fileUploadMapper.insert(upload);
                    upload.setUrl("");
                    list.add(upload);
                }
            } catch (Exception e) {
                if (stream != null) stream = null;
                if (in != null) in = null;
                if (filePath != null) filePath.delete();
                e.printStackTrace();
            }
        }
        return ResultGenerator.genSuccessResult(list);
    }

    /**
     * TODO  文件下载
     * @author wangchao
     * @date 2020/11/24 18:06
     * @param
     * @return
     */
    @Override
    public void download(String id, HttpServletRequest request, HttpServletResponse response) {
        FileUpload upload = fileUploadMapper.selectByPrimaryKey(id);
        if (upload == null) return;
        File file = new File(fileRootPath + "/" + upload.getUrl());

        if (file.exists()) {
            FileInputStream fis = null;
            try {
                String fileName = new String(upload.getName().getBytes(), "utf-8");
                fileName = URLEncoder.encode(fileName, "UTF-8");
                response.setContentType("application/octet-stream");
                response.addHeader("Content-Disposition",
                        "attachment;fileName=" + fileName);// 设置文件名
                response.setHeader("FileName", fileName);
                byte[] buffer = new byte[1024];
                fis = new FileInputStream(file);
                OutputStream os = response.getOutputStream();
                int i = fis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = fis.read(buffer);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * TODO  根据ID查询文件信息
     * @author wangchao
     * @date 2020/11/27 10:01
     * @param
     * @return
     */
    @Override
    public ResponseResult queryByIdFile(String id) throws Exception {
        try {
            FileUpload upload=new FileUpload();
            upload = fileUploadMapper.selectByPrimaryKey(id);
            return ResultGenerator.genSuccessResult(upload);
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultGenerator.genFailResult("查询文件失败");
    }

    /**
     * TODO  根据作品ID下载作品图片文件
     * @author wangchao
     * @date 2020/12/8 18:20
     * @param
     * @return
     */
    @Override
    public void downloadWorksFile(String workId, HttpServletRequest request, HttpServletResponse response) throws Exception {
        List<FileUpload> uploads = fileUploadMapper.queryByWorkIdFile(workId);
        if (uploads.size() == 0) return;
        //创建文件夹  将文件copy到文件夹中打成压缩包
        File saveFile = null;
        String path = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date()) + workId;
        String savepath=fileRootPath+path;
        saveFile = new File(savepath);
        if (!saveFile.exists()) {
            saveFile.mkdirs();
        }else {
            //清除文件夹内容
            deleteFolder(saveFile);
        }
        //循环取出作品图片文件
        for(FileUpload upload:uploads){
            File file = new File(fileRootPath + File.separator + upload.getUrl());
            copyFileUsingFileStreams(file,saveFile);
        }
        CompressUtil.generateFile(savepath,"rar");
        //下载zip文件
        File fileZip = new File(saveFile.getParent() + File.separator +"CompressFile" + File.separator + "ZP" +saveFile.getName()+".rar");
        if (fileZip.exists()) {
            FileInputStream fis = null;
            try {
                response.setContentType("application/octet-stream");
                response.addHeader("Content-Disposition",
                        "attachment;fileName=" + fileZip.getName());// 设置文件名
                response.setHeader("FileName", fileZip.getName());
                byte[] buffer = new byte[51200];
                fis = new FileInputStream(fileZip);
                OutputStream os = response.getOutputStream();
                int i = fis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = fis.read(buffer);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * TODO  递归删除文件
     * @author wangchao
     * @date 2020/12/9 11:17
     * @param
     * @return
     */
    private static void deleteFolder(File folder) throws Exception {
        if (!folder.exists()) {
            throw new Exception("文件不存在");
        }
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    //递归直到目录下没有文件
                    deleteFolder(file);
                } else {
                    //删除
                    file.delete();
                }
            }
        }
    }

    /**
     * TODO  copy文件
     * @author wangchao
     * @date 2020/12/9 11:39
     * @param
     * @return
     */
    private static void copyFileUsingFileStreams(File source, File dest)
            throws IOException {
        InputStream input = null;
        OutputStream output = null;
        try {
            input = new FileInputStream(source);
            output = new FileOutputStream(dest+ File.separator +source.getName());
            byte[] buf = new byte[1024];
            int len;
            while ((len=input.read(buf))!=-1) {
                output.write(buf, 0, len);
                output.flush();
            }
        } finally {
            input.close();
            output.close();
        }
    }
}
